package com.qf.electronic.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qf.electronic.common.R;
import com.qf.electronic.common.ResponseStatus;
import com.qf.electronic.dto.UserDto;
import com.qf.electronic.dto.UserStateDto;
import com.qf.electronic.excel.AbstractExcelExporter;
import com.qf.electronic.excel.AbstractExcelImporter;
import com.qf.electronic.pojo.User;
import com.qf.electronic.service.IUserService;
import com.qf.electronic.vo.InitializeVo;
import com.qf.electronic.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wu
 * @since 2023-05-04
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;



    @GetMapping("/init")
    public R<InitializeVo> initialize(Authentication authentication){
        //数据的组装是在控制层进行
        InitializeVo vo = new InitializeVo();
//        SecurityContext context = SecurityContextHolder.getContext();
//        Authentication authentication = context.getAuthentication();
        //security认证过后，这个UsernamePasswordAuthenticationToken中的principal
        //存储的就是用户对象
        User user = (User) authentication.getPrincipal();
        vo.setMenus(userService.getUserMenus(user.getUsername()));
        vo.setUser(user);
        return R.ok(vo);
    }

    @GetMapping
    public R<Page<UserVo>> searchUser(UserDto userDto){
        return R.ok(userService.getUsers(userDto));
    }

    @GetMapping("/item/{roleId}/{queryContent}")
    public R<List<User>> getUserItem(@PathVariable("roleId") Integer roleId, @PathVariable("queryContent")String queryContent){
        QueryWrapper<User> wrapper =new QueryWrapper<>();
        wrapper.eq("role_id", roleId);
        if(StringUtils.hasLength(queryContent))
            wrapper.like("name", queryContent);
        return R.ok(userService.list(wrapper));
    }


    @PostMapping
    public R<Boolean> addUser(@Valid @RequestBody User user, BindingResult result){
        if(result.hasFieldErrors()){//如果存在数据校验错误
            return R.error(ResponseStatus.INVALID_PARAMETER);
        }
        //增加用户的时候使用的默认密码
        String password = passwordEncoder.encode("666666");
        user.setPassword(password);
        return R.ok(userService.save(user));
    }

    @PutMapping
    public R<Boolean> updateUser(@Valid @RequestBody User user, BindingResult result){
        if(result.hasFieldErrors()){//如果存在数据校验错误
            return R.error(ResponseStatus.INVALID_PARAMETER);
        }
        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        wrapper.set("name", user.getName());
        wrapper.set("age", user.getAge());
        wrapper.set("sex", user.getSex());
        wrapper.set("phone", user.getPhone());
        wrapper.set("email", user.getEmail());
        wrapper.set("entry_time", user.getEntryTime());
        wrapper.set("leave_time", user.getLeaveTime());

        wrapper.eq("username", user.getUsername());
        wrapper.eq("delete_flag", 1);
        return R.ok(userService.update(wrapper));
    }

    @DeleteMapping
    public R<Boolean> deleteUser(@RequestParam("usernames") List<String> usernames){
        return R.ok(userService.removeByIds(usernames));
    }

    @PutMapping("/state")
    public R<Boolean> changeUserState(UserStateDto stateDto){
        return R.ok(userService.changeUserState(stateDto));
    }

    @PostMapping("/import")
    public R<Boolean> importUsers(@RequestPart("file")MultipartFile file){
        AbstractExcelImporter<User> userImporter = new AbstractExcelImporter<User>(User.class, 1000) {
            @Override
            protected void batchSaveData(List<User> dataList) {
                dataList.forEach(user -> user.setPassword(passwordEncoder.encode("666666")));
                userService.saveBatch(dataList);
            }
        };
        try {
            userImporter.importExcel(file.getInputStream());
            return R.ok(true);
        } catch (IOException e) {
            e.printStackTrace();
            return R.ok(false);
        }
    }

    @GetMapping("/export")
    public void exportUser(UserDto userDto, HttpServletResponse response) throws IOException {
        AbstractExcelExporter<User> userExporter = new AbstractExcelExporter<User>(User.class, 1000) {
            @Override
            protected long getExportCount(Map<String, Object> params) {
                return userService.getExportUserCount(params);
            }

            @Override
            protected List<User> getExportData(Map<String, Object> params, int page, int pageSize) {
                return userService.getExportUsers(params, page, pageSize);
            }
        };
        JSONObject json = (JSONObject) JSONObject.toJSON(userDto);
        String filename = new String("用户信息.xlsx".getBytes(), StandardCharsets.ISO_8859_1);
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + filename);
        userExporter.export(json, response.getOutputStream(), "用户信息表");
    }
}

